﻿$import( "SmitearWebGL.Core.Geometry.InputDataSet" );

SmitearWebGL.Core.Geometry.Geometry = {};

SmitearWebGL.Core.Geometry.Geometry.t_vec0 = $V3();
SmitearWebGL.Core.Geometry.Geometry.t_vec1 = $V3();

SmitearWebGL.Core.Geometry.Geometry.buildRawData = function( inputs, refIndices )
{
	var dataPerData = inputs[0].stride;
	var i, j, m;
	var iLen = inputs[0].indices.length;
	
	for ( i = 1; i < inputs.length; ++ i )
	{
		$THROW( iLen != 0 && iLen == inputs[i].indices.length, "各输入数据之间的索引长度不相同." );
		dataPerData += inputs[i].stride;
	}
	
	if ( ! refIndices )
	{
		refIndices = new Array( iLen );
		
		for ( i = 0; i < iLen; ++ i )
			refIndices[i] = i;
	}
	else
		$THROW( refIndices.length == iLen, "输出索引长度和输入索引长度不相同." );
	
	var newRawData = new Array( iLen * dataPerData );
	var input;
	var stride, refIndex, index, offset = 0;
	for ( i = 0; i < inputs.length; ++ i )
	{
		input = inputs[i];
		stride = input.stride;
		
		$THROW( stride != 0, "stride为零." );
		
		for ( j = 0; j < iLen; ++ j )
		{
			index = input.indices[j] * stride;
			refIndex = refIndices[j] * dataPerData + offset;
			for ( m = 0; m < stride; ++ m )
				newRawData[refIndex + m] = input.data[index+m];
		}
		
		offset += stride;
	}
	
	var output = new SmitearWebGL.Core.Geometry.InputDataSet( refIndices, newRawData, dataPerData );
	
	return output;
}

SmitearWebGL.Core.Geometry.Geometry.buildVertexAdjancency = function( vertexInput, output )
{
	var i, j, m;
	var data = vertexInput.data;
	var indices = vertexInput.indices;
	var stride = vertexInput.stride;
	
	if ( output == null )
		output = new Array( data.length / 3 );
	else
	{
		$THROW( output.length == data.length / 3, "输出数据长度无效." );
		
		for ( i = 0, m = output.length; i < m; ++ i )
			output[i] = null;
	}
	
	for ( i = 0, j = 0; i < indices.length; i += stride, ++ j )
	{
		for ( m = 0; m < stride; ++ m )
		{
			if ( output[indices[i+m]] == null ) output[indices[i+m]] = [];
			output[indices[i+m]].push( j );
		}
	}
	
	return output;
}

SmitearWebGL.Core.Geometry.Geometry.buildFaceNormal = function( vertexInput, output )
{
	var data = vertexInput.data;
	var indices = vertexInput.indices;
	var stride = vertexInput.stride;
	
	$THROW( stride > 2, "输入顶点数据无法构成面" );
	
	var len = indices.length;
	
	if ( output == null )
		output = new Array( len );
	else
		$THROW( output.length == len, "输出数据长度无效." );
	
	var tmp = new SmitearWebGL.Core.Math.Vector3();
	var index;
	var p0x, p0y, p0z, p1x, p1y, p1z, p2x, p2y, p2z;
	var t_vec0 = SmitearWebGL.Core.Geometry.Geometry.t_vec0;
	var t_vec1 = SmitearWebGL.Core.Geometry.Geometry.t_vec1;
	
	for ( var i = 0; i < len; i += 3 )
	{
		index = indices[i+0] * stride;
		p0x = data[index+0];
		p0y = data[index+1];
		p0z = data[index+2];
		
		index = indices[i+1] * stride;
		p1x = data[index+0];
		p1y = data[index+1];
		p1z = data[index+2];
		
		index = indices[i+2] * stride;
		p2x = data[index+0];
		p2y = data[index+1];
		p2z = data[index+2];
				
		t_vec0.reset( p1x - p0x, p1y - p0y, p1z - p0z );
		t_vec1.reset( p2x - p1x, p2y - p1y, p2z - p1z );
		
		SmitearWebGL.Core.Math.Vector3.cross( t_vec0, t_vec1, tmp );
		tmp.normalize();
		
		output[i+0] = tmp.x;
		output[i+1] = tmp.y;
		output[i+2] = tmp.z;
	}
	
	return output;
}

SmitearWebGL.Core.Geometry.Geometry.buildVertexNormal = function( inputDatas, adjs, fNormals, output )
{
	var i, n;
	var originalIndices = inputDatas.indices;
	var iLen = originalIndices.length;
	
	var newRawData;
	var refIndices;
	if ( output == null )
	{
		newRawData = new Array( iLen * 3 );
		refIndices = new Array( iLen );
		for ( i = 0; i < iLen; ++ i )
			refIndices[i] = i;
		output = new SmitearWebGL.Core.Geometry.InputDataSet( refIndices, newRawData, 3 );
	}
	else
	{
		if ( output.data == null )
			output.data = new Array( iLen * 3 );
		else
			$THROW( output.data.length == iLen * 3, "输出索引长度无效." );
		
		if ( output.indices == null )
		{
			output.indices = new Array( iLen );
			for ( i = 0; i < iLen; ++ i )
				output.indices[i] = i;
		}
		else
			$THROW( output.indices.length == iLen, "输出索引长度无效." );
		
		refIndices = output.indices;
		newRawData = output.data;
	}
	
	var index;
	var refIndex;
	var data;
	var t_vec0 = SmitearWebGL.Core.Geometry.Geometry.t_vec0;
	
	for ( i = 0; i < iLen; ++ i )
	{
		data = adjs[originalIndices[i]];
		t_vec0.reset( 0.0, 0.0, 0.0 );
		
		for ( n = 0; n < data.length; ++ n )
		{
			index = data[n] * 3;
			t_vec0.x += fNormals[index+0];
			t_vec0.y += fNormals[index+1];
			t_vec0.z += fNormals[index+2];
			
			t_vec0.normalize();
		}
		
		refIndex = refIndices[i] * 3;
		newRawData[refIndex+0] = t_vec0.x;
		newRawData[refIndex+1] = t_vec0.y;
		newRawData[refIndex+2] = t_vec0.z;
	}
	
	return output;
}

SmitearWebGL.Core.Geometry.Geometry.combineVertexDatas = function( vertexDataSet )
{
	var i, j, k, m, len, stride;
	
	var count = vertexDataSet[0].count;
	var data32per = vertexDataSet[0].data32PerVertex;
	
	for ( i = 1; i < vertexDataSet.length; ++ i )
	{
		$THROW( count == vertexDataSet[i].count, "合并的各顶点数据长度不一致." );
		data32per += vertexDataSet[i].data32PerVertex;
	}
	
	var newRawData = new Array( count * data32per );
	var offset = 0;
	
	for ( i = 0; i < vertexDataSet.length; ++ i )
	{
		stride = vertexDataSet[i].data32PerVertex;
		for ( j = 0, m = 0; j < newRawData.length; j += data32per, m += stride )
		{
			for ( k = 0; k < stride; ++ k )
			{
				newRawData[j + offset + k] = vertexDataSet[i].rawData[m+k];
			}
		}
		offset += stride;
	}
	
	return newRawData;
}

SmitearWebGL.Core.Geometry.Geometry.computeBoundingBoxByRawVertices = function( rawVertices )
{
	var data =[Number.MAX_VALUE, Number.MIN_VALUE,
		Number.MAX_VALUE, Number.MIN_VALUE, 
		Number.MAX_VALUE, Number.MIN_VALUE];
	
	for ( var i = 0; i < rawVertices.length; i += 3 )
	{
		var d0 = rawVertices[i + 0];
		var d1 = rawVertices[i + 1];
		var d2 = rawVertices[i + 2];
		
		data[0] = Math.min( data[0], d0 );
		data[2] = Math.min( data[2], d1 );
		data[4] = Math.min( data[4], d2 );
		
		data[1] = Math.max( data[1], d0 );
		data[3] = Math.max( data[3], d1 );
		data[5] = Math.max( data[5], d2 );
	}
	
	var boundingBox = new SmitearWebGL.Core.Geometry.BoundingBox();
	boundingBox.getLocalAABB().setVector( data );
	
	return boundingBox;
}

SmitearWebGL.Core.Geometry.Geometry.computeBoundingBoxByVertices = function( vertices )
{
	var data = [Number.MAX_VALUE, Number.MIN_VALUE,
		Number.MAX_VALUE, Number.MIN_VALUE, 
		Number.MAX_VALUE, Number.MIN_VALUE];
	
	for ( var i = 0; i < vertices.length; i ++ )
	{
		var d0 = vertices[i].x;
		var d1 = vertices[i].y;
		var d2 = vertices[i].z;
		
		data[0] = Math.min( data[0], d0 );
		data[2] = Math.min( data[2], d1 );
		data[4] = Math.min( data[4], d2 );
		
		data[1] = Math.max( data[1], d0 );
		data[3] = Math.max( data[3], d1 );
		data[5] = Math.max( data[5], d2 );
	}
	
	var boundingBox = new SmitearWebGL.Core.Geometry.BoundingBox();
	boundingBox.getLocalAABB().setVector( data );
	
	return boundingBox;
}

SmitearWebGL.Core.Geometry.Geometry.createShadowMesh = function( vertexInput )
{
	var j, i, f, k, i2;
	var len = vertexInput.indices.length / 3;
	var pNewVBData = new Array( len );
	var pdwNewIBData = new Array( len * 3 );
	var pMapping = new Array( pdwNewIBData.length );
	var pCorss = $V3();
	var nIndex;
	var nNextIndex = 0;
	var nNextVertex = 0;
	var nVertIndex;
	var dwNumEdges = pMapping.length;
	var nNumMaps = 0;
	var nVertShared, nBefore, nAfter;
	var p0x, p0y, p0z;
	var p1x, p1y, p1z;
	var p2x, p2y, p2z;
	var t_vec0 = SmitearWebGL.Core.Geometry.Geometry.t_vec0;
	var t_vec1 = SmitearWebGL.Core.Geometry.Geometry.t_vec1;
	
	var faceNormals = SmitearWebGL.Core.Geometry.Geometry.buildFaceNormal( vertexInput );
	
	function cloneVBData( data )
	{
		return {
			position : [data.position[0], data.position[1], data.position[2]],
			normal : [data.normal[0], data.normal[1], data.normal[2]]
		};
	}
	
	for ( f = 0; f < pMapping.length; ++ f )
		pMapping[f] = { m_anOldEdge : [-1, -1], m_aanNewEdge : [[-1, -1],[-1, -1]] };
	
	for ( f = 0, k = 0; f < len; ++ f, k += 3 )
	{
		pdwNewIBData[nNextIndex++] = k + 0;
		pdwNewIBData[nNextIndex++] = k + 1;
		pdwNewIBData[nNextIndex++] = k + 2;
		
		nIndex = vertexInput.indices[k + 0] * 3;
		pNewVBData[nNextVertex++] = {
			position : [vertexInput.data[nIndex+0], vertexInput.data[nIndex+1], vertexInput.data[nIndex+2]],
			normal : [faceNormals[k+0], faceNormals[k+1], faceNormals[k+2]]
		};
		
		nIndex = vertexInput.indices[k + 1] * 3;
		pNewVBData[nNextVertex++] = {
			position : [vertexInput.data[nIndex+0], vertexInput.data[nIndex+1], vertexInput.data[nIndex+2]],
			normal : [faceNormals[k+0], faceNormals[k+1], faceNormals[k+2]]
		};
		
		nIndex = vertexInput.indices[k + 2] * 3;
		pNewVBData[nNextVertex++] = {
			position : [vertexInput.data[nIndex+0], vertexInput.data[nIndex+1], vertexInput.data[nIndex+2]],
			normal : [faceNormals[k+0], faceNormals[k+1], faceNormals[k+2]]
		};
		
		// Edge 1
		nVertIndex = [vertexInput.indices[k + 0], vertexInput.indices[k + 1], vertexInput.indices[k + 2]];
		nIndex = SmitearWebGL.Core.Geometry.Geometry._findEdgeInMappingTable( nVertIndex[0], nVertIndex[1], pMapping, dwNumEdges );
		
		if( -1 == nIndex ) return null;
		
		if( pMapping[nIndex].m_anOldEdge[0] == -1 && pMapping[nIndex].m_anOldEdge[1] == -1 )
		{
			pMapping[nIndex].m_anOldEdge[0] = nVertIndex[0];
			pMapping[nIndex].m_anOldEdge[1] = nVertIndex[1];
			pMapping[nIndex].m_aanNewEdge[0][0] = k;
			pMapping[nIndex].m_aanNewEdge[0][1] = k + 1;
		
			++ nNumMaps;
		}
		else
		{
			$THROW( nNumMaps > 0, "nNumMaps error" );
		
			pMapping[nIndex].m_aanNewEdge[1][0] = k;
			pMapping[nIndex].m_aanNewEdge[1][1] = k + 1;
		
			// First triangle
			pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[0][1];
			pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[0][0];
			pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[1][0];
		
			// Second triangle
			pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[1][1];
			pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[1][0];
			pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[0][0];
		
			pMapping[nIndex] = pMapping[nNumMaps - 1];
			pMapping[nNumMaps - 1] = { m_anOldEdge : [-1, -1], m_aanNewEdge : [[-1, -1],[-1, -1]] };
			
			-- nNumMaps;
		}
		
		// Edge 2
		nIndex = SmitearWebGL.Core.Geometry.Geometry._findEdgeInMappingTable( nVertIndex[1], nVertIndex[2], pMapping, dwNumEdges );
		
		if( -1 == nIndex ) return null;
		
		if( pMapping[nIndex].m_anOldEdge[0] == -1 && pMapping[nIndex].m_anOldEdge[1] == -1 )
		{
			pMapping[nIndex].m_anOldEdge[0] = nVertIndex[1];
			pMapping[nIndex].m_anOldEdge[1] = nVertIndex[2];
			pMapping[nIndex].m_aanNewEdge[0][0] = k + 1;
			pMapping[nIndex].m_aanNewEdge[0][1] = k + 2;
		
			++nNumMaps;
		}
		else
		{
			$THROW( nNumMaps > 0, "nNumMaps error" );
		
			pMapping[nIndex].m_aanNewEdge[1][0] = k + 1;
			pMapping[nIndex].m_aanNewEdge[1][1] = k + 2;
		
			// First triangle
			pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[0][1];
			pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[0][0];
			pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[1][0];
		
			// Second triangle
			pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[1][1];
			pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[1][0];
			pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[0][0];
		
			pMapping[nIndex] = pMapping[nNumMaps - 1];
			pMapping[nNumMaps - 1] = { m_anOldEdge : [-1, -1], m_aanNewEdge : [[-1, -1],[-1, -1]] };
			
			--nNumMaps;
		}

		// Edge 3
		nIndex = SmitearWebGL.Core.Geometry.Geometry._findEdgeInMappingTable( nVertIndex[2], nVertIndex[0], pMapping, dwNumEdges );
		
		if( -1 == nIndex ) return null;
		
		if( pMapping[nIndex].m_anOldEdge[0] == -1 && pMapping[nIndex].m_anOldEdge[1] == -1 )
		{
			pMapping[nIndex].m_anOldEdge[0] = nVertIndex[2];
			pMapping[nIndex].m_anOldEdge[1] = nVertIndex[0];
			pMapping[nIndex].m_aanNewEdge[0][0] = k + 2;
			pMapping[nIndex].m_aanNewEdge[0][1] = k;
		
			++nNumMaps;
		}
		else
		{
			$THROW( nNumMaps > 0, "nNumMaps error" );
		
			pMapping[nIndex].m_aanNewEdge[1][0] = k + 2;
			pMapping[nIndex].m_aanNewEdge[1][1] = k;
		
			// First triangle
			pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[0][1];
			pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[0][0];
			pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[1][0];
		
			// Second triangle
			pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[1][1];
			pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[1][0];
			pdwNewIBData[nNextIndex++] = pMapping[nIndex].m_aanNewEdge[0][0];
		
			pMapping[nIndex] = pMapping[nNumMaps - 1];
			pMapping[nNumMaps - 1] = { m_anOldEdge : [-1, -1], m_aanNewEdge : [[-1, -1],[-1, -1]] };
			
			--nNumMaps;
		}
	}
	
	pNewVBData = pNewVBData.concat( new Array( nNumMaps * 3 ) );
	pdwNewIBData = pdwNewIBData.concat( new Array( nNumMaps * 7 * 3 ) );
	
	nNextVertex = len * 3;
	
	for( i = 0; i < nNumMaps; ++ i )
	{
		if( pMapping[i].m_anOldEdge[0] != -1 && pMapping[i].m_anOldEdge[1] != -1 )
		{
			if( pMapping[i].m_aanNewEdge[1][0] == -1 || pMapping[i].m_aanNewEdge[1][1] == -1 )
			{
				for( i2 = i + 1; i2 < nNumMaps; ++i2 )
				{
					if( pMapping[i2].m_anOldEdge[0] != -1 && pMapping[i2].m_anOldEdge[1] != -1 &&
					( pMapping[i2].m_aanNewEdge[1][0] == -1 || pMapping[i2].m_aanNewEdge[1][1] == -1 ) )
					{
						nVertShared = 0;
						
						if( pMapping[i2].m_anOldEdge[0] == pMapping[i].m_anOldEdge[1] )
							++nVertShared;
						
						if( pMapping[i2].m_anOldEdge[1] == pMapping[i].m_anOldEdge[0] )
							++nVertShared;
		
						if( 2 == nVertShared )
						{
							pMapping[i2].m_aanNewEdge[1][0] = pMapping[i].m_aanNewEdge[0][0];
							pMapping[i2].m_aanNewEdge[1][1] = pMapping[i].m_aanNewEdge[0][1];
							
							break;
						}
						else if( 1 == nVertShared )
						{
							if( pMapping[i2].m_anOldEdge[0] == pMapping[i].m_anOldEdge[1] )
							{
								nBefore = i;
								nAfter = i2;
							}
							else
							{
								nBefore = i2;
								nAfter = i;
							}
		
							pNewVBData[nNextVertex + 0] = cloneVBData( pNewVBData[pMapping[nAfter].m_aanNewEdge[0][1]] );
							pNewVBData[nNextVertex + 1] = cloneVBData( pNewVBData[pMapping[nBefore].m_aanNewEdge[0][1]] );
							pNewVBData[nNextVertex + 2] = cloneVBData( pNewVBData[pMapping[nBefore].m_aanNewEdge[0][0]] );
							
							// Recompute the normal
							p0x = pNewVBData[nNextVertex + 0].position[0];
							p0y = pNewVBData[nNextVertex + 0].position[1];
							p0z = pNewVBData[nNextVertex + 0].position[2];
							
							p1x = pNewVBData[nNextVertex + 1].position[0];
							p1y = pNewVBData[nNextVertex + 1].position[1];
							p1z = pNewVBData[nNextVertex + 1].position[2];
							
							p2x = pNewVBData[nNextVertex + 2].position[0];
							p2y = pNewVBData[nNextVertex + 2].position[1];
							p2z = pNewVBData[nNextVertex + 2].position[2];
									
							t_vec0.reset( p1x - p0x, p1y - p0y, p1z - p0z );
							t_vec1.reset( p2x - p1x, p2y - p1y, p2z - p1z );
							
							SmitearWebGL.Core.Math.Vector3.cross( t_vec0, t_vec1, pCorss );
							pCorss.normalize();
							
							pNewVBData[nNextVertex + 0].normal[0] = pNewVBData[nNextVertex + 1].normal[0] = pNewVBData[nNextVertex + 2].normal[0] = pCorss.x;
							pNewVBData[nNextVertex + 0].normal[1] = pNewVBData[nNextVertex + 1].normal[1] = pNewVBData[nNextVertex + 2].normal[1] = pCorss.y;
							pNewVBData[nNextVertex + 0].normal[2] = pNewVBData[nNextVertex + 1].normal[2] = pNewVBData[nNextVertex + 2].normal[2] = pCorss.z;
							
							pdwNewIBData[nNextIndex + 0] = nNextVertex;
							pdwNewIBData[nNextIndex + 1] = nNextVertex + 1;
							pdwNewIBData[nNextIndex + 2] = nNextVertex + 2;
		
							// 1st quad
		
							pdwNewIBData[nNextIndex + 3] = pMapping[nBefore].m_aanNewEdge[0][1];
							pdwNewIBData[nNextIndex + 4] = pMapping[nBefore].m_aanNewEdge[0][0];
							pdwNewIBData[nNextIndex + 5] = nNextVertex + 1;
		
							pdwNewIBData[nNextIndex + 6] = nNextVertex + 2;
							pdwNewIBData[nNextIndex + 7] = nNextVertex + 1;
							pdwNewIBData[nNextIndex + 8] = pMapping[nBefore].m_aanNewEdge[0][0];
		
							// 2nd quad
		
							pdwNewIBData[nNextIndex + 9] = pMapping[nAfter].m_aanNewEdge[0][1];
							pdwNewIBData[nNextIndex + 10] = pMapping[nAfter].m_aanNewEdge[0][0];
							pdwNewIBData[nNextIndex + 11] = nNextVertex;
		
							pdwNewIBData[nNextIndex + 12] = nNextVertex + 1;
							pdwNewIBData[nNextIndex + 13] = nNextVertex;
							pdwNewIBData[nNextIndex + 14] = pMapping[nAfter].m_aanNewEdge[0][0];
		
							if( pMapping[i2].m_anOldEdge[0] == pMapping[i].m_anOldEdge[1] )
							{
								pMapping[i2].m_anOldEdge[0] = pMapping[i].m_anOldEdge[0];
							}
							else
							{
								pMapping[i2].m_anOldEdge[1] = pMapping[i].m_anOldEdge[1];
							}
							pMapping[i2].m_aanNewEdge[0][0] = nNextVertex + 2;
							pMapping[i2].m_aanNewEdge[0][1] = nNextVertex;
		
							nNextVertex += 3;
							nNextIndex += 15;
		
							break;
						}
					}
				}
			}
			else
			{
				// First triangle
				pdwNewIBData[nNextIndex++] = pMapping[i].m_aanNewEdge[0][1];
				pdwNewIBData[nNextIndex++] = pMapping[i].m_aanNewEdge[0][0];
				pdwNewIBData[nNextIndex++] = pMapping[i].m_aanNewEdge[1][0];
		
				// Second triangle
				pdwNewIBData[nNextIndex++] = pMapping[i].m_aanNewEdge[1][1];
				pdwNewIBData[nNextIndex++] = pMapping[i].m_aanNewEdge[1][0];
				pdwNewIBData[nNextIndex++] = pMapping[i].m_aanNewEdge[0][0];
			}
		}
	}
	
	var vertices = [];
	var normals = [];
	var indices = [];
	for ( i = 0; i < pNewVBData.length; ++ i )
	{
		if ( pNewVBData[i] != undefined )
		{
			vertices.push( pNewVBData[i].position[0], pNewVBData[i].position[1], pNewVBData[i].position[2] );
			normals.push( pNewVBData[i].normal[0], pNewVBData[i].normal[1], pNewVBData[i].normal[2] );
		}
	}
	
	for ( i = 0; i < pdwNewIBData.length; ++ i )
	{
		if ( pdwNewIBData[i] != undefined )
		{
			indices.push( pdwNewIBData[i] );
		}
	}
			
	var inputDatas = [
		new SmitearWebGL.Core.Geometry.InputDataSet( indices, vertices, 3 ),
		new SmitearWebGL.Core.Geometry.InputDataSet( indices, normals, 3 )
	];
	
	var vOutputData = SmitearWebGL.Core.Geometry.Geometry.buildRawData( inputDatas );
	
	return vOutputData;
}

SmitearWebGL.Core.Geometry.Geometry._findEdgeInMappingTable = function( nV1, nV2, pMapping, nCount )
{
	for( var i = 0; i < nCount; ++i )
	{
		if( ( pMapping[i].m_anOldEdge[0] == -1 && pMapping[i].m_anOldEdge[1] == -1 ) ||
			( pMapping[i].m_anOldEdge[1] == nV1 && pMapping[i].m_anOldEdge[0] == nV2 ) )
		{
			return i;
		}
	}

	return -1;
}